package com.zb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.OrderTypeSelectVo;
import com.zb.entity.SelectVo;
import com.zb.entity.ZjWorkModuleType;
import com.zb.entity.ZjWorkModuleWay;
import com.zb.mapper.ZjWorkModuleTypeMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjWorkDetailService;
import com.zb.service.ZjWorkModuleTypeService;
import com.zb.vo.WorkModuleTypeListVo;
import com.zb.vo.WorkModuleTypeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 工单模块分类表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-09-15
 */
@Service
public class ZjWorkModuleTypeServiceImpl extends ServiceImpl<ZjWorkModuleTypeMapper, ZjWorkModuleType> implements ZjWorkModuleTypeService {
    @Resource
    private ZjWorkModuleTypeMapper workModuleTypeMapper;
    @Resource
    private ZjWorkDetailService workDetailService;

    // 新增或修改工单模块分类
    @Override
    public void save(Long custAccId, Long moduleId, WorkModuleTypeVo moduleTypeVo) {
        Assert.isTrue(null == workModuleTypeMapper.existByName(custAccId, moduleId, moduleTypeVo.getId(), moduleTypeVo.getName()), "分类名称已重复");
        ZjWorkModuleType type = new ZjWorkModuleType();
        BeanUtils.copyProperties(moduleTypeVo, type);
        type.setDisabled(moduleTypeVo.getStatus());
        if (null != type.getId()) {
            this.updateById(type);
            return;
        }
        type.setId(IdWorker.getId());
        type.setCustAccId(custAccId);
        type.setModuleId(moduleId);
        this.save(type);
    }

    // 获取模块分类列表
    @Override
    public Map<String, Object> getList(Long moduleId, SelectVo selectVo) {
        QueryWrapper<ZjWorkModuleType> wrapper = new QueryWrapper<>();
        wrapper.eq("module_id", moduleId).eq("parent_id", 0);
        wrapper.orderByDesc("sort", "gmt_update");
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        PageUtil.setPageLimit(selectVo);
        Page<ZjWorkModuleType> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);

        wrapper = new QueryWrapper<>();
        wrapper.eq("module_id", moduleId).gt("parent_id", 0);
        List<ZjWorkModuleType> childTypes = this.list(wrapper);

        List<WorkModuleTypeListVo> voList = page.getRecords().stream().map(type -> {
            WorkModuleTypeListVo vo = new WorkModuleTypeListVo();
            BeanUtils.copyProperties(type, vo);
            vo.setLevel(1);
            vo.setStatus(type.getDisabled());
            vo.setCreateTime(type.getGmtCreate());
            vo.setUpdateTime(type.getGmtUpdate());
            vo.setChildTypes(getChildType(type.getId(), 2, childTypes));
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    /**
     * 获取子级分类
     * @param id
     * @param childTypes
     * @return
     */
    private List<WorkModuleTypeListVo> getChildType(Long id, Integer level, List<ZjWorkModuleType> childTypes) {
       return childTypes.stream().filter(ct -> Objects.equals(id, ct.getParentId())).map(type -> {
            WorkModuleTypeListVo vo = new WorkModuleTypeListVo();
            BeanUtils.copyProperties(type, vo);
            vo.setLevel(level);
            vo.setStatus(type.getDisabled());
            vo.setCreateTime(type.getGmtCreate());
            vo.setUpdateTime(type.getGmtUpdate());
            vo.setChildTypes(getChildType(type.getId(), 3, childTypes));
            return  vo;
        }).toList();
    }

    // 根据ID批量启用或禁用模块分类
    @Override
    public void updateDisabledBatchById(List<Long> idList, boolean status) {
        if (null == idList || idList.isEmpty()) {
            return;
        }
        workModuleTypeMapper.updateDisabledBatchById(idList, status);
    }

    // 根据ID批量删除模块分类
    @Override
    public void deleteBatchById(List<Long> ids) {
        List<Long> typeIds = workDetailService.getByTypeIds(ids);
        if (!typeIds.isEmpty()) {
            String ways = workModuleTypeMapper.getByIds(typeIds).stream().map(ZjWorkModuleType::getName).collect(Collectors.joining("、"));
            Assert.isTrue(false, "分类[" + ways + "]已与工单关联，不可删除");
        }
        List<Long> removeIds = workModuleTypeMapper.getByIds(ids).stream().map(ZjWorkModuleType::getId).toList();
        this.removeByIds(removeIds);
    }

    // 工单模块分类下拉列表查询
    @Override
    public Map<String, Object> workModuleTypePageSelect(Long moduleId, SelectVo selectVo) {
        QueryWrapper<ZjWorkModuleType> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name");
        wrapper.eq("module_id", moduleId).eq("parent_id", 0).eq("is_disabled", false);
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        PageUtil.setSelectPageLimit(selectVo);
        Page<ZjWorkModuleType> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        List<Long> ids = page.getRecords().stream().map(ZjWorkModuleType::getId).toList();

        List<ZjWorkModuleType> types =  new ArrayList<>();
        if (CollectionUtils.isNotEmpty(ids)) {
            types.addAll(workModuleTypeMapper.getByParentIds(ids));
        }
        List<OrderTypeSelectVo> voList = page.getRecords().stream().map(type -> {
            OrderTypeSelectVo vo = new OrderTypeSelectVo(type.getId(), type.getName());
            vo.setSelectVos(getChild(vo.getId(), types));
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    public List<OrderTypeSelectVo> getChild(Long id, List<ZjWorkModuleType> childTypes) {
        return childTypes.stream().filter(type -> Objects.equals(id, type.getParentId())).map(t -> {
            OrderTypeSelectVo vo = new OrderTypeSelectVo(t.getId(), t.getName());
            vo.setSelectVos(getChild(vo.getId(), childTypes));
            return vo;
        }).toList();
    }

    // 获取模块分类名称
    @Override
    public String getNameByIds(Long oneTypeId, Long twoTypeId, Long threeTypeId) {
        if (null == oneTypeId) {
            return "";
        }
        List<Long> ids = new ArrayList<>();
        ids.add(oneTypeId);
        if (null == twoTypeId) ids.add(twoTypeId);
        if (null == threeTypeId) ids.add(threeTypeId);
        return workModuleTypeMapper.getNameByIds(ids);
    }


}
